import os, os.path
import urllib, urllib2
import ConfigParser

from connection import MysqlConnection
from message import Message 

# This is the 'client code'. The message sender.
# @param host - this is the remote host
# Usage:
#   msg_sender = MessageSender('http://localhost:8080')
#   msg_sender.send('Hahahah  hah hah ha I am a l33t Hax0r &$&&^(&!')
class MessageSender(object):
  def __init__(self, host):
    self.host = host
    self.message = None
    self.db_config = None
    self.db_config = self.get_db_config()
    
    # If sender_daemon is not running, run it
    MessageSender.control_daemon(self.host, 'restart')
    
  def __del__(self):
    # If sender_daemon is running, stop it
    MessageSender.control_daemon(self.host, 'stop')
    
  def set_message(self, message_obj):
    self.message = message_obj
    
  def get_db_config(self):
    if not self.db_config:
      default = {'host':'localhost', 'user':'root', 'password':'', 'core_db':'sms_db'}
      root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
      config = ConfigParser.RawConfigParser()
      config.read(os.path.join(root, 'conf', 'sender.conf'))
      default['host'] = config.get('database', 'host')
      default['user'] = config.get('database', 'user')
      default['password'] = config.get('database', 'password')
      default['core_db'] = config.get('database', 'core_db')
      return default
    else:
      return self.db_config
    
  def send(self, content=None):    
    '''
    send() can create new message or send existing message object
    '''
    message = None
    if self.message:
      message = self.message
      content = self.message.content
    else:
      if content:
        MysqlConnection(self.db_config)
        message = Message.create(content, Message.DIRECTION_OUT)
        
    if message and content:     
      # quote/encode the content, because it will be part of URL
      content = urllib.quote(content)
      
      # Send via HTTP
      try:
        self.conn = urllib2.urlopen(self.host + "/send/%s/%s" % (message.global_unique_id, content))     
        if self.conn:
          if self.conn.code == 200:
            message.status = Message.STATUS_SUCCESS
          else:
            message.status = Message.STATUS_FAILED
          self.conn.close()
        else:
          message.status = Message.STATUS_FAILED

      except Exception:
        message.status = Message.STATUS_FAILED
      
      MysqlConnection(self.db_config) 
      message.sync()
        
    return message
  
  # re_send method will be called by sender_daemon        
  def resend(self, status):
    #get outgoing messages with certain status, but not STATUS_SUCCESS
    if status != Message.STATUS_SUCCESS:
      MysqlConnection(self.db_config)
      resultset = Message.selectBy( direction=Message.DIRECTION_OUT, status=status )
      if resultset.count() > 0:
        for message in resultset:
          self.set_message(message)
          self.send()
  
  @classmethod      
  def control_daemon(cls, host, command):
    '''
      @param command can be: start|stop|restart
    ''' 
    root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
    if not os.path.exists(os.path.join(root, 'tmp', 'sender_daemon.pid')):
      os.system("../bin/sender_daemon.py '%s' %s" % (host, command))